import React, { Component } from 'react';
// import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as actions from '../actions/index';
import ListEmpty from 'atComponents/ListEmpty';
import { Badge, Button, Balloon, Animate, Input } from '@teamix/ui';
import { YunxiaoIcon, ButtonIcon, Tooltip } from '@alife/devops-ui';
import File from './file';
import CommentList from './components/comment';
import CodeScanList from './components/codeScan';
import track, { enterPage } from 'utils/track';
import {
  changeMrTabKey,
  getMergeRequest,
} from 'pages/index/pages/project/pages/projectMergeRequestDetail/actions';
import DiffSettingsBtn from 'pages/index/pages/project/pages/projectMergeRequestDetail/containers/components/diffSettingBtns';
import KEYCODE from 'utils/keycode';
import { ENUM } from 'utils/constants';
import debounce from 'lodash.debounce';
import intl from '../../../../../../../../../locale';
// import Watermark from 'components/watermark';
import utils from 'utils';
import { getFeature } from 'utils/features';

const { ctrlKey } = ENUM.getOSKeyMap();

class Root extends Component {
  constructor(props) {
    super(props);
    this.allFileScrollDebounce = debounce(this.allFileScroll, 50);
    this.container = null;
    this.imageObserver = null;
  }

  componentDidMount() {
    this.props.changeMrTabKey('changes');
    // // 自己实现路由
    window.addEventListener(
      'hashchange',
      (e) => {
        const hash = e.newURL.split('#')[1] || '';
        // 平铺模式下，将滚动高亮的key清空，设置滚动来自树,
        // https://teambition.alibaba-inc.com/task/5e71a6cd6a058f6ebf65095d
        if (this.props.forceCrFileViewType !== 'single') {
          this.props.updateData({
            leftTreeSelectKey: '',
            isScrollByTree: true,
          });
        }

        this.props.changeRouter(hash);
      },
      false,
    );

    // 初始路由
    const hash = window.location.href.split('#')[1] || '';
    this.props.changeRouter(hash);

    // 文件切换的快捷键
    document.addEventListener('keydown', this.handleKeyCodeEvent);

    // this.props.getCommitsRange(); // 获取commits区间
    // 监听滚动
    const container = document.querySelector('#mr-content-body');
    container.addEventListener('scroll', this.scroll);
    // 平铺模式时，根据滚动高亮左侧树
    if (this.props.forceCrFileViewType !== 'single') {
      container.addEventListener('scroll', this.allFileScrollDebounce);
    }

    const { codeReviewDetail } = this.props;
    enterPage('Repo-MR-changes', {
      mr_id: codeReviewDetail.id,
    });
    if (this.props.genWatermarkimage) {
      this.backageImageMutationObserver(); // 这个是水印相关的函数
    }
  }

  handleKeyCodeEvent = (e) => {
    if (e[ctrlKey] && e.shiftKey && e.keyCode === KEYCODE.UP) {
      this.props.goPreviousDiff();
    }
    if (e[ctrlKey] && e.shiftKey && e.keyCode === KEYCODE.DOWN) {
      this.props.goNextDiff();
    }
  };

  componentDidUpdate(prevProps) {
    const container = document.querySelector('#mr-content-body');
    if (prevProps.forceCrFileViewType === 'single' && this.props.forceCrFileViewType !== 'single') {
      // 页面滚动到顶部，第一个高亮
      this.resetActiveTree();
      container.addEventListener('scroll', this.allFileScrollDebounce);
    }
    if (prevProps.forceCrFileViewType !== 'single' && this.props.forceCrFileViewType === 'single') {
      container.removeEventListener('scroll', this.allFileScrollDebounce);
      this.resetActiveTree();
    }
  }

  resetActiveTree = () => {
    try {
      window.location.hash = '';
      document.querySelector('#mr-content-body').scrollTop = 0;
    } catch (e) {
      console.error(e);
    }
  };

  // 平铺模式滚动
  allFileScroll = () => {
    // 来自点击树的滚动不触发
    const { isScrollByTree } = this.props;
    if (isScrollByTree) {
      return;
    }
    // 平铺模式时，根据滚动高亮左侧树
    const files = document.querySelectorAll('.file-panel');
    let currentFile;
    for (let i = 0; i < files.length; i++) {
      const file = files[i];
      if (file.getBoundingClientRect().top < 250) {
        currentFile = file;
      } else {
        break;
      }
    }

    if (!currentFile) {
      return false;
    }

    const fileId = currentFile.getAttribute('id');
    const fileSha1 = fileId.replace('auchor_file_', '');

    // 滚动改变selectKeys
    this.props.updateData({
      leftTreeSelectKey: fileSha1,
    });

    // 平铺模式下滚动高亮左侧树时，开始记录时长
    this.props.getScrollTrackTime(fileSha1);
  };

  scroll = () => {
    const container = document.querySelector('#mr-content-body');
    const goToTopBtn = document.querySelector('.back-to-top');
    if (!goToTopBtn) {
      return;
    }
    if (container.scrollTop) {
      goToTopBtn.style.display = 'flex';
    } else {
      goToTopBtn.style.display = 'none';
    }
  };

  componentWillUnmount() {
    const container = document.querySelector('#mr-content-body');
    container.removeEventListener('scroll', this.scroll);
    container.removeEventListener('scroll', this.allFileScroll);
    this.props.updateData({
      isShowCodeScan: false,
      isShowComment: false,
      hash: {},
    });

    // this.props.resetData();
    document.removeEventListener('keydown', this.handleKeyCodeEvent);
    this.imageObserver && this.imageObserver.disconnect();
  }

  backageImageMutationObserver = () => {
    // 选择需要观察变动的节点
    const targetNode = this.container;
    // 观察器的配置（需要观察什么变动）
    const config = { attributes: true, childList: true, subtree: true };
    // 当观察到变动时执行的回调函数
    const callback = (mutationsList) => {
      // Use traditional 'for loops' for IE 11
      for (const mutation of mutationsList) {
        if (mutation.type === 'attributes') {
          targetNode.style.backgroundImage = utils.isGenWatermarkimage(
            this.props.genWatermarkimage,
          );
        }
      }
    };
    // 创建一个观察器实例并传入回调函数
    this.imageObserver = new MutationObserver(callback);
    // 以上述配置开始观察目标节点
    targetNode && this.imageObserver.observe(targetNode, config);
  };

  handleFilterComment = (value) => {
    const { codeReviewDetail } = this.props;
    if (value) {
      track({
        action: 'view_show_comments',
        page: 'Repo-MR-changes',
        mr_id: codeReviewDetail.id,
      });
    } else {
      track({
        action: 'view_no_show_comments',
        page: 'Repo-MR-changes',
        mr_id: codeReviewDetail.id,
      });
    }
    this.props.changeCommentsVisibleStatus(value ? 'all' : 'none');
  };

  goToTop = () => {
    const container = document.querySelector('#mr-content-body');
    container.scrollTop = 0;
  };

  refreshAllCommits = () => {
    const { origin, pathname } = window.location;
    window.location.href = `${origin}${pathname}`;
  };

  renderNoChange = () => {
    return (
      <div className="mr-changes-none">
        <ListEmpty
          image="none"
          content={intl.get({
            id: 'code-assets.changes.containers.root.NoChangesHaveBeenMade',
            defaultMessage: '当前评审没有任何改动',
          })}
        />
      </div>
    );
  };

  render() {
    const {
      commentsVisibleStatus,
      isShowComment,
      isShowCodeScan,
      commits,
      isPushRecordsFetched,
      issueDetailList,
      diffs,
      isShowExpiredPage,
      isDiffFetched,
      codeReviewDetail,
      genWatermarkimage,
    } = this.props;

    return (
      // <Watermark genWatermarkimage={genWatermarkimage}>
      <div
        ref={(el) => {
          this.container = el;
        }}
        className="change-tab"
        style={{
          backgroundImage: utils.isGenWatermarkimage(genWatermarkimage) || '',
        }}
      >
        {/* 因tab组件,up/down会切换tab，此处使之失焦 */}
        <Input autoFocus style={{ position: 'absolute', top: 0, left: '-1000px' }} />
        <Balloon.Tooltip
          trigger={
            <div className="back-to-top" onClick={this.goToTop}>
              <YunxiaoIcon type="arrow-up-2-line" />
            </div>
          }
          align="t"
        >
          {intl.get({
            id: 'code-assets.changes.containers.root.BackToTheTop',
            defaultMessage: '回到顶部',
          })}
        </Balloon.Tooltip>
        {this.props.diffTooLargeFlag === 'true' || isShowExpiredPage ? (
          <div className="mr-changes-large">
            <ListEmpty
              image="none"
              content={''}
              desc={
                isShowExpiredPage ? (
                  <div className="expire-text">
                    {intl.get({
                      id: 'code-assets.changes.containers.root.UnableToFindTheSubmitted',
                      defaultMessage: '由于强制提交，无法找到提交版本，可查看',
                    })}

                    <Button type="primary" text onClick={this.refreshAllCommits}>
                      {intl.get({
                        id: 'code-assets.changes.containers.root.SubmitAll',
                        defaultMessage: '全部提交',
                      })}
                    </Button>
                  </div>
                ) : (
                  intl.get({
                    id: 'code-assets.changes.containers.root.TheDiffContentIsToo',
                    defaultMessage:
                      'diff内容过大（文本内容超过50M或改动文件大于10000个），请在本地进行评审',
                  })
                )
              }
            />
          </div>
        ) : (
          <React.Fragment>
            {isPushRecordsFetched && !commits.length ? (
              this.renderNoChange()
            ) : (
              <React.Fragment>
                {isDiffFetched && !diffs.length ? (
                  this.renderNoChange()
                ) : (
                  <>
                    {/* 固定在右侧的icon */}
                    <div className="changes-right-icon-wrapper">
                      <div className="changes-right-icon-wrapper-guide">
                        {
                          getFeature('project.mr.diff.right_panel.scan') && (
                            <div>
                              <Tooltip
                                active={!isShowCodeScan}
                                align="l"
                                trigger={
                                  <span
                                    className="mr-comment-icon"
                                    onClick={() => {
                                      track({
                                        action: 'view_scan_panel',
                                        page: 'Repo-MR-changes',
                                        mr_id: codeReviewDetail.id,
                                      });

                                      this.props.updateData({
                                        isShowCodeScan: !isShowCodeScan,
                                        isShowComment: !isShowCodeScan ? false : isShowComment,
                                      });
                                    }}
                                  >
                                    <Badge count={issueDetailList.length}>
                                      <ButtonIcon name="test-grey-fill" />
                                    </Badge>
                                  </span>
                                }
                              >
                                {intl.get({
                                  id: 'code-assets.changes.containers.root.AutomatedScanning',
                                  defaultMessage: '自动化扫描',
                                })}
                              </Tooltip>
                            </div>
                          )
                        }
                        <div>
                          <Tooltip
                            active={!isShowComment}
                            align="l"
                            trigger={
                              <span
                                className="mr-comment-icon"
                                onClick={() => {
                                  track({
                                    action: 'view_comments_panel',
                                    page: 'Repo-MR-changes',
                                    mr_id: codeReviewDetail.id,
                                  });

                                  this.props.updateData({
                                    isShowComment: !isShowComment,
                                    // 开启一个关闭一个
                                    isShowCodeScan: !isShowComment ? false : isShowCodeScan,
                                  });
                                }}
                              >
                                <ButtonIcon name="message-line" />
                              </span>
                            }
                          >
                            {intl.get({
                              id: 'code-assets.changes.containers.root.Comments',
                              defaultMessage: '评论',
                            })}
                          </Tooltip>
                        </div>
                      </div>
                      <div>
                        <DiffSettingsBtn
                          {...this.props}
                          handleFilterComment={this.handleFilterComment}
                        />
                      </div>
                    </div>
                    <div className="changes-container">
                      <div
                        className={`changes-container-right ${
                          commentsVisibleStatus === 'none' ? 'no-comment' : 'has-comment'
                        } ${
                          isShowComment || (isShowCodeScan && isPushRecordsFetched)
                            ? 'has-panel'
                            : ''
                        }`}
                      >
                        <File {...this.props} />
                      </div>
                    </div>
                  </>
                )}

                <Animate
                  animation={{
                    enter: 'slideInRight',
                    leave: 'slideOutRight',
                  }}
                >
                  {isShowComment ? (
                    <CommentList {...this.props} isShowComment={isShowComment} />
                  ) : null}
                </Animate>
                {
                  getFeature('project.mr.diff.right_panel.scan') && (
                    <Animate
                      animation={{
                        enter: 'slideInRight',
                        leave: 'slideOutRight',
                      }}
                    >
                      {isShowCodeScan && isPushRecordsFetched ? (
                        <CodeScanList {...this.props} isShowCodeScan={isShowCodeScan} />
                      ) : null}
                    </Animate>
                  )
                }
              </React.Fragment>
            )}
          </React.Fragment>
        )}
      </div>
      // </Watermark>
    );
  }
}

export default connect(
  (state) => {
    const { root, changesReducer } = state.project.projectMergeRequestDetail;
    return {
      ...root,
      ...changesReducer,
      rootCodeReviewDetail: root.codeReviewDetail,
      changesReducer,
      genWatermarkimage: state.project.root.genWatermarkimage,
    };
  },
  (dispatch) => bindActionCreators({ ...actions, changeMrTabKey, getMergeRequest }, dispatch),
)(Root);
